﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Net;
using System.Net.Mail;
using System.Windows.Forms;
using ApplLogic.ApplClasses;
using TCPClient.RequestsToServerHandlers;
using TCPClient.UI.LogicForUserControls;

namespace TCPClient.UI.UserControls
{

    public enum eViewType
    {
        Requests,
        Registrations,
        Diff
    }

    [Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof (IDesigner))]
    public partial class ScMainUserControl : UserControl
    {
        private eViewType m_ViewType = eViewType.Registrations;
        public event EventHandler DateChanged = null;


        public ScMainUserControl()
        {
            InitializeComponent();
        }

        private void notifyObservers(DateTime start, DateTime end)
        {
            if(DateChanged != null)
            {
                DateEventArgs eventArgs = new DateEventArgs {StartTime = start, EndTime = end};
                DateChanged.Invoke(this, eventArgs);
            }
        }

        public RequestsToServerHandler WorkerRequestHandler 
        {
            set
            {
                ScMainUserControlLogic.Create(value);
                setAllDefaults();
            }
        }

        private void setViewAs(eViewType type)
        {
            const bool k_Editable = true;
            switch(type)
            {
                case eViewType.Requests:
                    m_ViewType = eViewType.Requests;
                    if(ScMainUserControlLogic.Instance.StartTimeOfTheWeek.Date <= DateTime.Now 
                       /* ScMainUserControlLogic.Instance.GetAllRegisteredShifts().Count > 0 */)
                    {
                        setButtonVisibility(false);
                        redGreenSelectionUserControl1.ChangeEditingStatus(!k_Editable);
                    }
                    else
                    {
                        setButtonVisibility(true);
                        redGreenSelectionUserControl1.ChangeEditingStatus(k_Editable);
                    }

                    break;
                case eViewType.Registrations:
                    m_ViewType = eViewType.Registrations;
                    setButtonVisibility(false);
                    redGreenSelectionUserControl1.ChangeEditingStatus(!k_Editable);
                    break;
                case eViewType.Diff:
                    m_ViewType = eViewType.Diff;
                    setButtonVisibility(false);
                    redGreenSelectionUserControl1.ChangeEditingStatus(!k_Editable);
                    break;

            }
        }

        private void setButtonVisibility(bool visible)
        {
            buttonUpdateRequests.Visible = visible;
            buttonCopyFromLastWeek.Visible = visible;
            buttonSpecialRequests.Visible = visible;
        }

        private void setAllDefaults()
        {
            registerToTheTabsClickEvents();
            setViewAs(eViewType.Registrations);
            initTheWeekControlAndDays();
            drawShiftsAccordingToTheViewState();
        }

        private void drawShiftsAccordingToTheViewState()
        {
            switch (m_ViewType)
            {
                case eViewType.Registrations:
                    drawShiftsThatWorkersRegisterdTo();
                    break;
                case eViewType.Requests:
                    drawShiftsThatWorkersRequested();
                    break;
            }
        }

        private void registerToTheTabsClickEvents()
        {
            tabControlRegisterdAndRequired.Selected += tabControl_Selected;
        }

        private void tabControl_Selected(object sender, EventArgs e)
        {
            setAllShiftsDataAccordingtoTab((e as TabControlEventArgs).TabPage.Text);
        }

        private void setAllShiftsDataAccordingtoTab(string dataTab)
        {
            const bool k_CleanBoard = true;
            if (dataTab == eViewType.Registrations.ToString())
            {
                setViewAs(eViewType.Registrations);
                weekTableUserControl1.SetWeekData(ScMainUserControlLogic.Instance.StartTimeOfTheWeek,
                                 ScMainUserControlLogic.Instance.EndTimeOfTheWeek);
                drawShiftsThatWorkersRegisterdTo();

            }
            else if (dataTab == eViewType.Requests.ToString())
            {
                setViewAs(eViewType.Requests);
                weekTableUserControl1.SetWeekData(ScMainUserControlLogic.Instance.StartTimeOfTheWeek,
                  ScMainUserControlLogic.Instance.EndTimeOfTheWeek);
                drawShiftsThatWorkersRequested();

            }
            else // diff
            {
                setViewAs(eViewType.Diff);
                weekTableUserControl1.SetWeekData(ScMainUserControlLogic.Instance.StartTimeOfTheWeek,
                    ScMainUserControlLogic.Instance.EndTimeOfTheWeek);
                drawShiftsThatWorkersRequested();
                drawShiftsThatWorkersRegisterdTo(!k_CleanBoard);

            }
        }

        private void drawShiftsThatWorkersRegisterdTo(bool cleanBoard = true)
        {
            if (cleanBoard)
            {
                weekTableUserControl1.CleanWeekBoard();
            }
            foreach (var shift in ScMainUserControlLogic.Instance.GetAllRegisteredShifts())
            {
                weekTableUserControl1.DrawShiftsThatWorkersRegisterdTo(shift.BeginTime, shift.EndTime);
            }
        }

        private void drawShiftsThatWorkersRequested(bool cleanBoard = true)
        {
            if (cleanBoard)
            {
                weekTableUserControl1.CleanWeekBoard();
            }
            foreach (var shift in ScMainUserControlLogic.Instance.GetAllWantedShifts())
            {
                weekTableUserControl1.DrawShiftsThatWorkersRequested(shift.BeginTime, shift.EndTime, eType.WANTED);
            }
            foreach (var shift in ScMainUserControlLogic.Instance.GetAllForbiddenShifts())
            {
                weekTableUserControl1.DrawShiftsThatWorkersRequested(shift.BeginTime, shift.EndTime, eType.FORBIDDEN);
            }
        }

        private void initTheWeekControlAndDays()
        {
            weekTableUserControl1.SetWeekData(ScMainUserControlLogic.Instance.StartTimeOfTheWeek, ScMainUserControlLogic.Instance.EndTimeOfTheWeek);
            weekTableUserControl1.SetTheGreenRedControlToEachShiftCell(redGreenSelectionUserControl1);

        }

        private void buttonUpdateRequests_Click(object sender, EventArgs e)
        {
            List<ShiftRequestFromGUI> requests = new List<ShiftRequestFromGUI>();
            foreach (var dayInWeek in weekTableUserControl1.Days)
            {
                foreach (var shiftInDay in dayInWeek.ShiftsInDay)
                {
                    if (shiftInDay.CurrentState == eCurrentState.Green || shiftInDay.CurrentState == eCurrentState.Red)
                    {
                        requests.Add(new ShiftRequestFromGUI()
                                         {
                                             EndDate = shiftInDay.EndTime,
                                             StartDate = shiftInDay.StartTime,
                                             Type = shiftInDay.CurrentState == eCurrentState.Green ? eType.WANTED : eType.FORBIDDEN,
                                         });
                    }
                }
            }
            ScMainUserControlLogic.Instance.UpdateServerWithWorkerRequest(requests);
            MessageBox.Show(@"Your request was successfully updated", @"Update Successfull", MessageBoxButtons.OK, MessageBoxIcon.Information);

        }

        private void monthCalendar1_DateChanged(object sender, DateRangeEventArgs e)
        {
            ScMainUserControlLogic.Instance.CaclulateStartAndEndTimeOfTheWeek(e.Start);
            setAllShiftsDataAccordingtoTab(this.tabControlRegisterdAndRequired.SelectedTab.Text);
            notifyObservers(ScMainUserControlLogic.Instance.StartTimeOfTheWeek, ScMainUserControlLogic.Instance.EndTimeOfTheWeek);
        }

        public void RefreshAll()
        {
            setAllShiftsDataAccordingtoTab(tabControlRegisterdAndRequired.SelectedTab.Text);
        }

        private void buttonCopyFromLastWeek_Click(object sender, EventArgs e)
        {
            ScMainUserControlLogic.Instance.CopyRequestFrom();
            MessageBox.Show(@"Your request was successfully updated", @"Update Successfull", MessageBoxButtons.OK, MessageBoxIcon.Information);
            RefreshAll();
        }

        private void buttonSpecialRequests_Click(object sender, EventArgs e)
        {
            SpecialRequestsOfWorkerForm spf = new SpecialRequestsOfWorkerForm(this);
            spf.ShowDialog();

        }

        public WeekTableUserControl WeekTableUserControl
        {
            get { return weekTableUserControl1; }
            
        }

    }
    public class DateEventArgs: EventArgs
    {
        public DateTime StartTime { get; set; }
        public DateTime EndTime { get; set; }
    }

}
